package com.example.shuiyin.service.impl;

import com.example.shuiyin.dto.BatchProcessRequest;
import com.example.shuiyin.dto.ProcessResultDto;
import com.example.shuiyin.dto.TaskStatusDto;
import com.example.shuiyin.dto.UploadResultDto;
import com.example.shuiyin.dto.WatermarkAddRequest;
import com.example.shuiyin.dto.WatermarkProcessRequest;
import com.example.shuiyin.dto.WatermarkRemoveRequest;
import com.example.shuiyin.dto.watermark.TaskStatusResult;
import com.example.shuiyin.dto.watermark.WatermarkHistoryResponse;
import com.example.shuiyin.dto.watermark.WatermarkTaskResult;
import com.example.shuiyin.entity.WatermarkRecord;
import com.example.shuiyin.entity.User;
import com.example.shuiyin.entity.Task;
import com.example.shuiyin.exception.AppException;
import com.example.shuiyin.exception.ErrorCode;
import com.example.shuiyin.mapper.WatermarkRecordMapper;
import com.example.shuiyin.mapper.TaskMapper;
import com.example.shuiyin.service.AuthService;
import com.example.shuiyin.service.MinioStorageService;
import com.example.shuiyin.service.QuotaService;
import com.example.shuiyin.service.UserService;
import com.example.shuiyin.service.WatermarkService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.core.task.TaskExecutor;

@Service
@RequiredArgsConstructor
@Slf4j
public class WatermarkServiceImpl implements WatermarkService {

    // 注入所需的依赖
    private final AuthService authService;
    private final ObjectMapper objectMapper;
    private final WatermarkRecordMapper watermarkRecordMapper;
    private final UserService userService;
    private final MinioStorageService storageService;
    private final RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private SimpMessagingTemplate messagingTemplate;
    
    private final QuotaService quotaService;
    
    @Autowired
    private TaskMapper taskMapper;
    
    @Autowired
    @org.springframework.beans.factory.annotation.Qualifier("taskExecutor")
    private TaskExecutor taskExecutor;
    
    private static final String TASK_PROGRESS_KEY = "task:progress:";
    private static final long PROGRESS_EXPIRE_TIME = 24 * 60 * 60; // 24小时

    // 定义缺失的内部类
    private static class TaskProgressUpdate {
        private final String taskId;
        private final int progress;
        
        public TaskProgressUpdate(String taskId, int progress) {
            this.taskId = taskId;
            this.progress = progress;
        }
        
        public String getTaskId() { return taskId; }
        public int getProgress() { return progress; }
    }

    @Override
    public UploadResultDto uploadImage(MultipartFile file, Long userId) throws IOException {
        log.info("用户[{}]上传图片: {}", userId, file.getOriginalFilename());
        
        // 检查文件类型
        String contentType = file.getContentType();
        if (contentType == null || !contentType.startsWith("image/")) {
            throw new AppException("不支持的文件类型，仅支持图片文件", ErrorCode.UNSUPPORTED_FILE_TYPE);
        }
        
        // 检查文件大小
        if (file.getSize() > 10 * 1024 * 1024) { // 限制10MB
            throw new AppException("文件大小超过限制(10MB)", ErrorCode.FILE_TOO_LARGE);
        }
        
        // 生成唯一文件名
        String fileId = UUID.randomUUID().toString();
        String originalFilename = file.getOriginalFilename();
        String extension = originalFilename != null ? 
                originalFilename.substring(originalFilename.lastIndexOf(".")) : ".jpg";
        String objectName = String.format("watermark/original/%d/%s%s", userId, fileId, extension);
        
        try {
            // 上传到MinIO
            String fileUrl = storageService.uploadFile(file, objectName);
            
            // 创建图片元数据对象，可以是DTO或数据库实体
            // TODO: 保存到数据库
            
            return UploadResultDto.builder()
                    .imageId(fileId)
                    .originalName(originalFilename)
                    .previewUrl(fileUrl)
                    .mimeType(contentType)
                    .size(file.getSize())
                    .width(800) // TODO: 获取实际宽度
                    .height(600) // TODO: 获取实际高度
                    .build();
        } catch (Exception e) {
            log.error("上传图片失败: {}", e.getMessage(), e);
            throw new AppException("上传图片失败: " + e.getMessage(), ErrorCode.FILE_UPLOAD_ERROR);
        }
    }

    @Override
    public ProcessResultDto addWatermark(WatermarkAddRequest request, Long userId) {
        log.info("用户[{}]添加水印: {}", userId, request);
        
        // 验证请求参数
        if (request.getImageId() == null || request.getImageId().isEmpty()) {
            throw new AppException("图片ID不能为空", ErrorCode.INVALID_PARAMETER);
        }
        
        // 检查用户配额
        if (!quotaService.hasProcessingQuota(userId)) {
            throw new AppException("处理配额不足", ErrorCode.QUOTA_EXCEEDED);
        }
        
        try {
            // 查询原图信息
            // TODO: 从数据库获取原图信息
            
            // 创建任务记录
            Task task = new Task();
            task.setTaskId(generateTaskId());
            task.setUserId(userId);
            task.setType("ADD");
            task.setStatus("PROCESSING");
            task.setTotalItems(1);
            task.setProcessedItems(0);
            task.setParameters(convertParamsToJson(request));
            task.setCreatedAt(LocalDateTime.now());
            task.setUpdatedAt(LocalDateTime.now());
            
            taskMapper.insert(task);
            
            // 异步处理水印添加
            CompletableFuture.runAsync(() -> {
                processWatermarkTask(task, request);
            });
            
            // 记录配额使用
            quotaService.recordProcessingUsage(userId);
            
            // 创建并返回初步结果
            String resultId = UUID.randomUUID().toString();
            return ProcessResultDto.builder()
                    .resultId(resultId)
                    .processType("add-watermark")
                    .downloadUrl("/api/watermark/download/" + resultId)
                    .build();
        } catch (AppException e) {
            throw e;
        } catch (Exception e) {
            log.error("添加水印失败: {}", e.getMessage(), e);
            throw new AppException("添加水印失败: " + e.getMessage(), ErrorCode.WATERMARK_PROCESS_ERROR);
        }
    }

    @Override
    public ProcessResultDto removeWatermark(WatermarkRemoveRequest request, Long userId) {
        // TODO: 实现去除水印功能
        log.info("用户[{}]去除水印: {}", userId, request);
        
        // 临时实现，用于避免自动装配错误
        return ProcessResultDto.builder()
                .resultId(UUID.randomUUID().toString())
                .previewUrl("/temp/result.jpg")
                .originalImageId(request.getImageId())
                .processType("remove-watermark")
                .processTime(1500L)
                .width(800)
                .height(600)
                .downloadUrl("/api/watermark/download/" + UUID.randomUUID())
                .build();
    }

    @Override
    public String batchProcess(BatchProcessRequest request, Long userId) {
        // TODO: 实现批量处理功能
        log.info("用户[{}]批量处理: {}", userId, request);
        
        // 临时实现，用于避免自动装配错误
        return UUID.randomUUID().toString();
    }

    @Override
    public TaskStatusDto getTaskStatus(String taskId, Long userId) {
        // TODO: 实现获取任务状态功能
        log.info("用户[{}]获取任务状态: {}", userId, taskId);
        
        // 临时实现，用于避免自动装配错误
        return TaskStatusDto.builder()
                .taskId(taskId)
                .status("processing")
                .total(5)
                .completed(2)
                .failed(0)
                .startTime(System.currentTimeMillis() - 10000)
                .endTime(0L)
                .message("处理中")
                .build();
    }

    @Override
    public Resource getProcessResultFile(String resultId, Long userId) {
        // TODO: 实现获取处理结果文件功能
        log.info("用户[{}]获取处理结果文件: {}", userId, resultId);
        
        try {
            // 临时实现，用于避免自动装配错误
            Path tempFile = Files.createTempFile("result-", ".jpg");
            return new UrlResource(tempFile.toUri());
        } catch (IOException e) {
            log.error("创建临时文件失败", e);
            throw new RuntimeException("获取文件失败", e);
        }
    }

    @Override
    public String getProcessResultFilename(String resultId) {
        // TODO: 实现获取处理结果文件名功能
        return "result-" + resultId + ".jpg";
    }

    @Override
    public List<WatermarkHistoryResponse> getUserWatermarkHistory(Long userId, int page, int size) {
        log.info("获取用户[{}]水印历史记录, page={}, size={}", userId, page, size);
        
        // TODO: 从数据库中查询用户的水印历史记录
        // 这里是模拟数据，实际实现应该查询数据库
        List<WatermarkHistoryResponse> historyList = new ArrayList<>();
        
        // 模拟几条历史记录
        for (int i = 0; i < size; i++) {
            WatermarkHistoryResponse record = new WatermarkHistoryResponse();
            record.setId((long) (i + 1));
            record.setOriginalUrl("https://example.com/original/image" + (i + 1) + ".jpg");
            record.setWatermarkedUrl("https://example.com/watermarked/image" + (i + 1) + ".jpg");
            record.setWatermarkType(i % 2 == 0 ? "TEXT" : "IMAGE");
            record.setWatermarkContent(i % 2 == 0 ? "Copyright 2024" : "https://example.com/logo.png");
            record.setFileType("IMAGE");
            record.setStatus("COMPLETED");
            record.setCreatedAt(LocalDateTime.now().minusDays(i));
            record.setUpdatedAt(LocalDateTime.now().minusDays(i));
            
            historyList.add(record);
        }
        
        return historyList;
    }

    @Override
    public AuthService getAuthService() {
        return authService;
    }
    
    @Override
    public WatermarkAddRequest convertToAddRequest(Map<String, Object> requestMap) {
        try {
            log.debug("转换WatermarkAddRequest: {}", requestMap);
            return objectMapper.convertValue(requestMap, WatermarkAddRequest.class);
        } catch (Exception e) {
            log.error("转换WatermarkAddRequest失败", e);
            throw new RuntimeException("转换请求对象失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public WatermarkRemoveRequest convertToRemoveRequest(Map<String, Object> requestMap) {
        try {
            log.debug("转换WatermarkRemoveRequest: {}", requestMap);
            return objectMapper.convertValue(requestMap, WatermarkRemoveRequest.class);
        } catch (Exception e) {
            log.error("转换WatermarkRemoveRequest失败", e);
            throw new RuntimeException("转换请求对象失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public BatchProcessRequest convertToBatchRequest(Map<String, Object> requestMap) {
        try {
            log.debug("转换BatchProcessRequest: {}", requestMap);
            return objectMapper.convertValue(requestMap, BatchProcessRequest.class);
        } catch (Exception e) {
            log.error("转换BatchProcessRequest失败", e);
            throw new RuntimeException("转换请求对象失败: " + e.getMessage(), e);
        }
    }

    @Override
    public List<WatermarkRecord> getWatermarkHistoryByUserId(Long userId) {
        return watermarkRecordMapper.selectByUserIdOrderByCreatedAtDesc(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WatermarkTaskResult createProcessTask(Long userId, WatermarkProcessRequest request) {
        if (userId == null) {
            throw new AppException("用户ID不能为空", ErrorCode.INVALID_PARAMETER);
        }
        
        if (request == null) {
            throw new AppException("处理请求不能为空", ErrorCode.INVALID_PARAMETER);
        }
        
        // 验证用户是否存在
        User user = userService.findById(userId);
        if (user == null) {
            throw new AppException("用户不存在", ErrorCode.USER_NOT_FOUND);
        }
        
        // 生成任务ID
        String taskId = UUID.randomUUID().toString().replace("-", "");
        
        // 创建Task对象而不是WatermarkTask对象
        Task task = Task.builder()
                .taskId(taskId)
                .userId(userId)
                .type(request.getProcessType()) // 使用processType作为type
                .status("PENDING")
                .totalItems(1)  // 默认处理1个项目
                .processedItems(0)
                .successItems(0)
                .failedItems(0)
                .parameters(convertParamsToJson(request))
                .createdAt(LocalDateTime.now())
                .updatedAt(LocalDateTime.now())
                .build();
        
        // 保存任务
        taskMapper.insert(task);
        
        // 异步执行处理逻辑
        taskExecutor.execute(() -> {
            try {
                processTask(task, request);
            } catch (Exception e) {
                log.error("处理水印任务失败: {}", e.getMessage(), e);
                // 更新任务状态为失败
                task.setStatus("FAILED");
                task.setErrorMessage(e.getMessage());
                task.setUpdatedAt(LocalDateTime.now());
                taskMapper.updateById(task);
            }
        });
        
        // 返回任务结果
        return WatermarkTaskResult.builder()
                .taskId(taskId)
                .status("PENDING")
                .build();
    }
    
    @Override
    public TaskStatusResult getTaskStatus(String taskId) {
        Task task = taskMapper.selectByTaskId(taskId);
        if (task == null) {
            return TaskStatusResult.builder()
                    .taskId(taskId)
                    .status("NOT_FOUND")
                    .progress(0)
                    .build();
        }
        
        Integer progress = task.getProcessedItems() != null && task.getTotalItems() != null && task.getTotalItems() > 0 
                ? (int)((task.getProcessedItems() * 100) / task.getTotalItems()) : 0;
        
        return TaskStatusResult.builder()
                .taskId(taskId)
                .status(task.getStatus())
                .progress(progress)
                .resultPath(task.getResultUrl())
                .errorMessage(task.getErrorMessage())
                .build();
    }
    
    @Override
    public TaskStatusResult getTaskStatus(Long userId, String taskId) {
        Task task = taskMapper.selectByTaskIdAndUserId(taskId, userId);
        if (task == null) {
            return TaskStatusResult.builder()
                    .taskId(taskId)
                    .status("NOT_FOUND")
                    .progress(0)
                    .build();
        }
        
        Integer progress = task.getProcessedItems() != null && task.getTotalItems() != null && task.getTotalItems() > 0 
                ? (int)((task.getProcessedItems() * 100) / task.getTotalItems()) : 0;
        
        return TaskStatusResult.builder()
                .taskId(taskId)
                .status(task.getStatus())
                .progress(progress)
                .resultPath(task.getResultUrl())
                .errorMessage(task.getErrorMessage())
                .build();
    }
    
    /**
     * 更新任务进度(减少数据库写入)
     */
    private void updateTaskProgress(String taskId, int progress) {
        // 正确存储进度值与过期时间
        redisTemplate.opsForValue().set(TASK_PROGRESS_KEY + taskId, progress, PROGRESS_EXPIRE_TIME, TimeUnit.SECONDS);
        
        // 发布WebSocket消息
        TaskProgressUpdate update = new TaskProgressUpdate(taskId, progress);
        messagingTemplate.convertAndSend("/topic/task/" + taskId, update);
    }
    
    /**
     * 更新任务状态(写入数据库)
     */
    private void updateTaskStatus(String taskId, String status, String errorMessage) {
        Task task = taskMapper.selectByTaskId(taskId);
        if (task == null) {
            throw new RuntimeException("任务不存在: " + taskId);
        }
        
        task.setStatus(status);
        task.setUpdatedAt(LocalDateTime.now());
        
        if (errorMessage != null) {
            task.setErrorMessage(errorMessage);
        }
        
        // 完成或失败时，设置进度
        if (status.equals("COMPLETED")) {
            task.setProcessedItems(task.getTotalItems());
            task.setSuccessItems(task.getTotalItems());
        }
        
        // 使用MyBatis-Plus方法更新
        taskMapper.updateById(task);
    }
    
    // 其他辅助方法...

    private String convertParamsToJson(Object params) {
        try {
            return objectMapper.writeValueAsString(params);
        } catch (Exception e) {
            log.error("转换参数到JSON失败: {}", e.getMessage(), e);
            return "{}";
        }
    }

    private String generateTaskId() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    private void processWatermarkTask(Task task, Object request) {
        try {
            if (request instanceof WatermarkProcessRequest) {
                processTask(task, (WatermarkProcessRequest) request);
            } else if (request instanceof WatermarkAddRequest) {
                // 转换WatermarkAddRequest为WatermarkProcessRequest
                WatermarkAddRequest addRequest = (WatermarkAddRequest) request;
                WatermarkProcessRequest processRequest = new WatermarkProcessRequest();
                processRequest.setProcessType("IMAGE_WATERMARK"); // 默认为图片水印
                processRequest.setSourceFileId(addRequest.getImageId());
                processRequest.setText(addRequest.getText());
                processRequest.setWatermarkType("TEXT");
                processRequest.setPosition("CENTER"); // 默认中心位置，可从addRequest中获取具体位置
                
                // 处理任务
                processTask(task, processRequest);
            } else {
                throw new Exception("不支持的请求类型: " + request.getClass().getName());
            }
        } catch (Exception e) {
            log.error("处理水印任务失败: {}", e.getMessage(), e);
            // 更新任务状态为失败
            task.setStatus("FAILED");
            task.setErrorMessage(e.getMessage());
            task.setUpdatedAt(LocalDateTime.now());
            taskMapper.updateById(task);
        }
    }

    // 添加处理方法
    private void processTask(Task task, WatermarkProcessRequest request) throws Exception {
        // 处理任务的具体逻辑
        log.info("开始处理任务: {}", task.getTaskId());
        
        updateTaskProgress(task.getTaskId(), 25);
        
        // 更新任务状态为处理中
        task.setStatus("PROCESSING");
        task.setStartTime(LocalDateTime.now());
        taskMapper.updateById(task);
        
        try {
            // 根据request中的参数实现具体处理逻辑
            updateTaskProgress(task.getTaskId(), 50);
            
            // TODO: 根据processType和参数处理不同类型的水印任务
            String resultPath = null;
            switch(request.getProcessType()) {
                case "IMAGE_WATERMARK":
                    resultPath = processImageWatermarkTask(task, request);
                    break;
                case "VIDEO_WATERMARK":
                    resultPath = processVideoWatermarkTask(task, request);
                    break;
                case "AUDIO_WATERMARK":
                    resultPath = processAudioWatermarkTask(task, request);
                    break;
                case "PDF_WATERMARK":
                    resultPath = processPdfWatermarkTask(task, request);
                    break;
                default:
                    throw new Exception("不支持的处理类型: " + request.getProcessType());
            }
            
            updateTaskProgress(task.getTaskId(), 75);
            
            // 处理完成后更新任务状态
            task.setStatus("COMPLETED");
            task.setProcessedItems(task.getTotalItems());
            task.setSuccessItems(task.getTotalItems());
            task.setResultUrl(resultPath);
            task.setEndTime(LocalDateTime.now());
            taskMapper.updateById(task);
            
            updateTaskProgress(task.getTaskId(), 100);
            
            // 记录处理历史
            if (resultPath != null) {
                recordWatermarkHistory(task, request, resultPath);
            }
            
        } catch (Exception e) {
            // 处理失败
            task.setStatus("FAILED");
            task.setFailedItems(task.getTotalItems());
            task.setErrorMessage(e.getMessage());
            task.setEndTime(LocalDateTime.now());
            taskMapper.updateById(task);
            throw e;
        }
    }
    
    private String processImageWatermarkTask(Task task, WatermarkProcessRequest request) throws Exception {
        // 模拟图片水印处理
        Thread.sleep(1000);
        // 返回生成的图片路径
        return "watermark/result/" + task.getUserId() + "/" + UUID.randomUUID() + ".jpg";
    }

    private String processVideoWatermarkTask(Task task, WatermarkProcessRequest request) throws Exception {
        // 检查文件类型
        String contentType = request.getSourceFileName() != null ? request.getSourceFileName() : request.getSourceFilePath();
        if (contentType == null || !contentType.startsWith("video/")) {
            throw new AppException("不支持的文件类型，仅支持视频文件", ErrorCode.UNSUPPORTED_FILE_TYPE);
        }
        
        // 检查文件大小
        if (request.getSourceFilePath() != null && request.getSourceFilePath().length() > 100 * 1024 * 1024) { // 限制100MB
            throw new AppException("文件大小超过限制(100MB)", ErrorCode.FILE_TOO_LARGE);
        }
        
        // 1. 上传原始文件
        String fileId = UUID.randomUUID().toString();
        String originalFilename = request.getSourceFileName();
        String extension = originalFilename != null ? 
                originalFilename.substring(originalFilename.lastIndexOf(".")) : ".mp4";
        String objectName = String.format("watermark/original/%d/%s%s", task.getUserId(), fileId, extension);
        
        try {
            // 上传到MinIO，使用文件路径而非MultipartFile
            String fileUrl = storageService.uploadFile(request.getSourceFilePath(), request.getSourceFileName(), objectName);
            
            // 2. 创建水印处理请求
            WatermarkProcessRequest processRequest = new WatermarkProcessRequest();
            processRequest.setSourceFileId(fileId);
            processRequest.setSourceFilePath(fileUrl);
            processRequest.setSourceFileName(originalFilename);
            processRequest.setProcessType("VIDEO_WATERMARK");
            processRequest.setText(request.getText());
            processRequest.setPosition(request.getPosition());
            processRequest.setFontSize(request.getFontSize());
            processRequest.setFontColor(request.getFontColor());
            processRequest.setOpacity(request.getOpacity());
            
            // 3. 创建并开始处理任务
            WatermarkTaskResult taskResult = createProcessTask(task.getUserId(), processRequest);
            
            // 4. 异步处理水印添加
            CompletableFuture.runAsync(() -> {
                try {
                    processTask(taskMapper.selectByTaskId(taskResult.getTaskId()), processRequest);
                } catch (Exception e) {
                    log.error("异步处理视频水印任务失败: {}", e.getMessage(), e);
                }
            });
            
            return taskResult.getTaskId();
        } catch (Exception e) {
            log.error("处理视频水印失败: {}", e.getMessage(), e);
            throw new AppException("处理视频水印失败: " + e.getMessage(), ErrorCode.WATERMARK_PROCESS_ERROR);
        }
    }

    private String processAudioWatermarkTask(Task task, WatermarkProcessRequest request) throws Exception {
        // 检查文件类型
        String contentType = request.getSourceFileName() != null ? request.getSourceFileName() : request.getSourceFilePath();
        if (contentType == null || !contentType.startsWith("audio/")) {
            throw new AppException("不支持的文件类型，仅支持音频文件", ErrorCode.UNSUPPORTED_FILE_TYPE);
        }
        
        // 检查文件大小
        if (request.getSourceFilePath() != null && request.getSourceFilePath().length() > 50 * 1024 * 1024) { // 限制50MB
            throw new AppException("文件大小超过限制(50MB)", ErrorCode.FILE_TOO_LARGE);
        }
        
        // 1. 上传原始文件
        String fileId = UUID.randomUUID().toString();
        String originalFilename = request.getSourceFileName();
        String extension = originalFilename != null ? 
                originalFilename.substring(originalFilename.lastIndexOf(".")) : ".mp3";
        String objectName = String.format("watermark/original/%d/%s%s", task.getUserId(), fileId, extension);
        
        try {
            // 上传到MinIO，使用文件路径而非MultipartFile
            String fileUrl = storageService.uploadFile(request.getSourceFilePath(), request.getSourceFileName(), objectName);
            
            // 2. 创建水印处理请求
            WatermarkProcessRequest processRequest = new WatermarkProcessRequest();
            processRequest.setSourceFileId(fileId);
            processRequest.setSourceFilePath(fileUrl);
            processRequest.setSourceFileName(originalFilename);
            processRequest.setProcessType("AUDIO_WATERMARK");
            processRequest.setText(request.getText());
            // 音频水印不需要位置、字体大小、颜色等视觉参数，但保留参数以统一接口
            processRequest.setPosition(request.getPosition());
            processRequest.setFontSize(request.getFontSize());
            processRequest.setFontColor(request.getFontColor());
            processRequest.setOpacity(request.getOpacity());
            
            // 3. 创建并开始处理任务
            WatermarkTaskResult taskResult = createProcessTask(task.getUserId(), processRequest);
            
            // 4. 异步处理水印添加
            CompletableFuture.runAsync(() -> {
                try {
                    processTask(taskMapper.selectByTaskId(taskResult.getTaskId()), processRequest);
                } catch (Exception e) {
                    log.error("异步处理音频水印任务失败: {}", e.getMessage(), e);
                }
            });
            
            return taskResult.getTaskId();
        } catch (Exception e) {
            log.error("处理音频水印失败: {}", e.getMessage(), e);
            throw new AppException("处理音频水印失败: " + e.getMessage(), ErrorCode.WATERMARK_PROCESS_ERROR);
        }
    }

    private String processPdfWatermarkTask(Task task, WatermarkProcessRequest request) throws Exception {
        // 检查文件类型
        String contentType = request.getSourceFileName() != null ? request.getSourceFileName() : request.getSourceFilePath();
        if (contentType == null || !contentType.equals("application/pdf")) {
            throw new AppException("不支持的文件类型，仅支持PDF文件", ErrorCode.UNSUPPORTED_FILE_TYPE);
        }
        
        // 检查文件大小
        if (request.getSourceFilePath() != null && request.getSourceFilePath().length() > 20 * 1024 * 1024) { // 限制20MB
            throw new AppException("文件大小超过限制(20MB)", ErrorCode.FILE_TOO_LARGE);
        }
        
        // 1. 上传原始文件
        String fileId = UUID.randomUUID().toString();
        String originalFilename = request.getSourceFileName();
        String extension = ".pdf";
        String objectName = String.format("watermark/original/%d/%s%s", task.getUserId(), fileId, extension);
        
        try {
            // 上传到MinIO，使用文件路径而非MultipartFile
            String fileUrl = storageService.uploadFile(request.getSourceFilePath(), request.getSourceFileName(), objectName);
            
            // 2. 创建水印处理请求
            WatermarkProcessRequest processRequest = new WatermarkProcessRequest();
            processRequest.setSourceFileId(fileId);
            processRequest.setSourceFilePath(fileUrl);
            processRequest.setSourceFileName(originalFilename);
            processRequest.setProcessType("PDF_WATERMARK");
            processRequest.setText(request.getText());
            processRequest.setPosition(request.getPosition());
            processRequest.setFontSize(request.getFontSize());
            processRequest.setFontColor(request.getFontColor());
            processRequest.setOpacity(request.getOpacity());
            
            // 3. 创建并开始处理任务
            WatermarkTaskResult taskResult = createProcessTask(task.getUserId(), processRequest);
            
            // 4. 异步处理水印添加
            CompletableFuture.runAsync(() -> {
                try {
                    processTask(taskMapper.selectByTaskId(taskResult.getTaskId()), processRequest);
                } catch (Exception e) {
                    log.error("异步处理PDF水印任务失败: {}", e.getMessage(), e);
                }
            });
            
            return taskResult.getTaskId();
        } catch (Exception e) {
            log.error("处理PDF水印失败: {}", e.getMessage(), e);
            throw new AppException("处理PDF水印失败: " + e.getMessage(), ErrorCode.WATERMARK_PROCESS_ERROR);
        }
    }

    private void recordWatermarkHistory(Task task, WatermarkProcessRequest request, String resultPath) {
        try {
            // 添加到用户的水印历史记录
            WatermarkRecord record = new WatermarkRecord();
            record.setUserId(task.getUserId());
            record.setWatermarkedUrl(resultPath);
            record.setWatermarkType(request.getWatermarkType() != null ? request.getWatermarkType() : "TEXT");
            record.setWatermarkContent(request.getText());
            
            // 根据处理类型设置文件类型
            if (request.getProcessType().contains("IMAGE")) {
            record.setFileType("IMAGE");
            } else if (request.getProcessType().contains("VIDEO")) {
                record.setFileType("VIDEO");
            } else if (request.getProcessType().contains("AUDIO")) {
                record.setFileType("AUDIO");
            } else if (request.getProcessType().contains("PDF")) {
                record.setFileType("PDF");
            } else {
                record.setFileType("OTHER");
            }
            
            record.setStatus("COMPLETED");
            record.setCreatedAt(LocalDateTime.now());
            record.setUpdatedAt(LocalDateTime.now());
            watermarkRecordMapper.insert(record);
        } catch (Exception e) {
            log.error("记录水印历史失败: {}", e.getMessage(), e);
            // 不中断主流程
        }
    }
    
    // JSON转换方法
    private String convertToJson(Object obj) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            return mapper.writeValueAsString(obj);
        } catch (Exception e) {
            log.error("JSON转换失败: {}", e.getMessage(), e);
            return "{}";
        }
    }
    
    // JSON解析方法
    private Map<String, Object> parseJson(String json) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            return mapper.readValue(json, new TypeReference<Map<String, Object>>() {});
        } catch (Exception e) {
            log.error("JSON解析失败: {}", e.getMessage(), e);
            return new HashMap<>();
        }
    }

    @Override
    public String processImageWatermark(MultipartFile file, String text, String position, Integer fontSize, 
            String fontColor, Float opacity, Long userId) throws IOException {
        log.info("用户[{}]处理图片水印: 文本={}, 位置={}", userId, text, position);
        
        // 1. 校验并上传原始文件
        UploadResultDto uploadResult = uploadImage(file, userId);
        
        // 2. 创建水印处理请求
        WatermarkProcessRequest request = new WatermarkProcessRequest();
        request.setSourceFileId(uploadResult.getImageId());
        request.setProcessType("IMAGE_WATERMARK");
        request.setText(text);
        request.setPosition(position);
        request.setFontSize(fontSize);
        request.setFontColor(fontColor);
        request.setOpacity(opacity);
        
        // 3. 创建并开始处理任务
        WatermarkTaskResult taskResult = createProcessTask(userId, request);
        
        // 4. 异步处理水印添加
        CompletableFuture.runAsync(() -> {
            try {
                Task task = taskMapper.selectByTaskId(taskResult.getTaskId());
                if (task != null) {
                    processTask(task, request);
                } else {
                    log.error("找不到任务: {}", taskResult.getTaskId());
                }
            } catch (Exception e) {
                log.error("异步处理图片水印任务失败: {}", e.getMessage(), e);
            }
        });
        
        return taskResult.getTaskId();
    }
    
    @Override
    public String processVideoWatermark(MultipartFile file, String text, String position, Integer fontSize, 
            String fontColor, Float opacity, Long userId) throws IOException {
        log.info("用户[{}]处理视频水印: 文本={}, 位置={}", userId, text, position);
        
        // 检查文件类型
        String contentType = file.getContentType();
        if (contentType == null || !contentType.startsWith("video/")) {
            throw new AppException("不支持的文件类型，仅支持视频文件", ErrorCode.UNSUPPORTED_FILE_TYPE);
        }
        
        // 检查文件大小
        if (file.getSize() > 100 * 1024 * 1024) { // 限制100MB
            throw new AppException("文件大小超过限制(100MB)", ErrorCode.FILE_TOO_LARGE);
        }
        
        // 1. 上传原始文件
        String fileId = UUID.randomUUID().toString();
        String originalFilename = file.getOriginalFilename();
        String extension = originalFilename != null ? 
                originalFilename.substring(originalFilename.lastIndexOf(".")) : ".mp4";
        String objectName = String.format("watermark/original/%d/%s%s", userId, fileId, extension);
        
        try {
            // 上传到MinIO
            String fileUrl = storageService.uploadFile(file, objectName);
            
            // 2. 创建水印处理请求
            WatermarkProcessRequest processRequest = new WatermarkProcessRequest();
            processRequest.setSourceFileId(fileId);
            processRequest.setSourceFilePath(fileUrl);
            processRequest.setSourceFileName(originalFilename);
            processRequest.setProcessType("VIDEO_WATERMARK");
            processRequest.setText(text);
            processRequest.setPosition(position);
            processRequest.setFontSize(fontSize);
            processRequest.setFontColor(fontColor);
            processRequest.setOpacity(opacity);
            
            // 3. 创建并开始处理任务
            WatermarkTaskResult taskResult = createProcessTask(userId, processRequest);
            
            // 4. 异步处理水印添加
            CompletableFuture.runAsync(() -> {
                try {
                    Task task = taskMapper.selectByTaskId(taskResult.getTaskId());
                    if (task != null) {
                        processTask(task, processRequest);
                    } else {
                        log.error("找不到任务: {}", taskResult.getTaskId());
                    }
                } catch (Exception e) {
                    log.error("异步处理视频水印任务失败: {}", e.getMessage(), e);
                }
            });
            
            return taskResult.getTaskId();
        } catch (Exception e) {
            log.error("处理视频水印失败: {}", e.getMessage(), e);
            throw new AppException("处理视频水印失败: " + e.getMessage(), ErrorCode.WATERMARK_PROCESS_ERROR);
        }
    }
    
    @Override
    public String processAudioWatermark(MultipartFile file, String text, String position, Integer fontSize, 
            String fontColor, Float opacity, Long userId) throws IOException {
        log.info("用户[{}]处理音频水印: 文本={}", userId, text);
        
        // 检查文件类型
        String contentType = file.getContentType();
        if (contentType == null || !contentType.startsWith("audio/")) {
            throw new AppException("不支持的文件类型，仅支持音频文件", ErrorCode.UNSUPPORTED_FILE_TYPE);
        }
        
        // 检查文件大小
        if (file.getSize() > 50 * 1024 * 1024) { // 限制50MB
            throw new AppException("文件大小超过限制(50MB)", ErrorCode.FILE_TOO_LARGE);
        }
        
        // 1. 上传原始文件
        String fileId = UUID.randomUUID().toString();
        String originalFilename = file.getOriginalFilename();
        String extension = originalFilename != null ? 
                originalFilename.substring(originalFilename.lastIndexOf(".")) : ".mp3";
        String objectName = String.format("watermark/original/%d/%s%s", userId, fileId, extension);
        
        try {
            // 上传到MinIO
            String fileUrl = storageService.uploadFile(file, objectName);
            
            // 2. 创建水印处理请求
            WatermarkProcessRequest processRequest = new WatermarkProcessRequest();
            processRequest.setSourceFileId(fileId);
            processRequest.setSourceFilePath(fileUrl);
            processRequest.setSourceFileName(originalFilename);
            processRequest.setProcessType("AUDIO_WATERMARK");
            processRequest.setText(text);
            // 音频水印不需要位置、字体大小、颜色等视觉参数，但保留参数以统一接口
            processRequest.setPosition(position);
            processRequest.setFontSize(fontSize);
            processRequest.setFontColor(fontColor);
            processRequest.setOpacity(opacity);
            
            // 3. 创建并开始处理任务
            WatermarkTaskResult taskResult = createProcessTask(userId, processRequest);
            
            // 4. 异步处理水印添加
            CompletableFuture.runAsync(() -> {
                try {
                    Task task = taskMapper.selectByTaskId(taskResult.getTaskId());
                    if (task != null) {
                        processTask(task, processRequest);
                    } else {
                        log.error("找不到任务: {}", taskResult.getTaskId());
                    }
                } catch (Exception e) {
                    log.error("异步处理音频水印任务失败: {}", e.getMessage(), e);
                }
            });
            
            return taskResult.getTaskId();
        } catch (Exception e) {
            log.error("处理音频水印失败: {}", e.getMessage(), e);
            throw new AppException("处理音频水印失败: " + e.getMessage(), ErrorCode.WATERMARK_PROCESS_ERROR);
        }
    }
    
    @Override
    public String processPdfWatermark(MultipartFile file, String text, String position, Integer fontSize, 
            String fontColor, Float opacity, Long userId) throws IOException {
        log.info("用户[{}]处理PDF水印: 文本={}, 位置={}", userId, text, position);
        
        // 检查文件类型
        String contentType = file.getContentType();
        if (contentType == null || !contentType.equals("application/pdf")) {
            throw new AppException("不支持的文件类型，仅支持PDF文件", ErrorCode.UNSUPPORTED_FILE_TYPE);
        }
        
        // 检查文件大小
        if (file.getSize() > 20 * 1024 * 1024) { // 限制20MB
            throw new AppException("文件大小超过限制(20MB)", ErrorCode.FILE_TOO_LARGE);
        }
        
        // 1. 上传原始文件
        String fileId = UUID.randomUUID().toString();
        String originalFilename = file.getOriginalFilename();
        String extension = ".pdf";
        String objectName = String.format("watermark/original/%d/%s%s", userId, fileId, extension);
        
        try {
            // 上传到MinIO
            String fileUrl = storageService.uploadFile(file, objectName);
            
            // 2. 创建水印处理请求
            WatermarkProcessRequest processRequest = new WatermarkProcessRequest();
            processRequest.setSourceFileId(fileId);
            processRequest.setSourceFilePath(fileUrl);
            processRequest.setSourceFileName(originalFilename);
            processRequest.setProcessType("PDF_WATERMARK");
            processRequest.setText(text);
            processRequest.setPosition(position);
            processRequest.setFontSize(fontSize);
            processRequest.setFontColor(fontColor);
            processRequest.setOpacity(opacity);
            
            // 3. 创建并开始处理任务
            WatermarkTaskResult taskResult = createProcessTask(userId, processRequest);
            
            // 4. 异步处理水印添加
            CompletableFuture.runAsync(() -> {
                try {
                    Task task = taskMapper.selectByTaskId(taskResult.getTaskId());
                    if (task != null) {
                        processTask(task, processRequest);
                    } else {
                        log.error("找不到任务: {}", taskResult.getTaskId());
                    }
                } catch (Exception e) {
                    log.error("异步处理PDF水印任务失败: {}", e.getMessage(), e);
                }
            });
            
            return taskResult.getTaskId();
        } catch (Exception e) {
            log.error("处理PDF水印失败: {}", e.getMessage(), e);
            throw new AppException("处理PDF水印失败: " + e.getMessage(), ErrorCode.WATERMARK_PROCESS_ERROR);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WatermarkTaskResult createWatermarkTask(WatermarkProcessRequest request, Long userId) {
        return createProcessTask(userId, request);
    }

    // 辅助方法：将WatermarkProcessRequest转换为JSON参数
    private String convertParamsToJson(WatermarkProcessRequest request) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.writeValueAsString(request);
        } catch (Exception e) {
            log.error("转换任务参数为JSON失败", e);
            return "{}";
        }
    }
} 